package br.com.traineApplication.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaQuery;

/**
 * 
 * Classe criada para gerar um novo dao genérico em tempo de execução, onde você não consegue descobrir o tipo parametrizado que foi passado como argumento.
 * porem não precisa se preocupar com a instanciação de uma nova classe DAO.
 * 
 * @author Josivam Rodrigues
 *
 * @param <T>
 */
public class DAO<T> {
	
	/**
	 * Váriavel de referencia
	 */
	private final Class<T> classe;

	/**
	 * Método construtor responsável por setar o tipo de objeto (Classe) para a variavel de referencia.
	 * @param classe
	 */
	public DAO(Class<T> classe) {
		this.classe = classe;
	}
	
	/**
	 *  Método responsável por adiciona dado de um objeto.<br/>
	 *  Onde este metedo recebe um Objeto e persiste este mesmo no banco de Dados.
	 * @param t
	 */
	public void adiciona(T t) {
		// consegue a entity manager
		EntityManager em = new JPAUtil().getEntityManager();
		// abre transacao
		em.getTransaction().begin();
		// persiste o objeto
		em.persist(t);
		// commita a transacao
		em.getTransaction().commit();
		// fecha a entity manager
		em.close();
	}

	public void remove(T t) {
		EntityManager em = new JPAUtil().getEntityManager();
		em.getTransaction().begin();

		em.remove(em.merge(t));

		em.getTransaction().commit();
		em.close();
	}

	public void atualiza(T t) {
		EntityManager em = new JPAUtil().getEntityManager();
		em.getTransaction().begin();

		em.merge(t);

		em.getTransaction().commit();
		em.close();
	}

	public List<T> listaTodos() {
		EntityManager em = new JPAUtil().getEntityManager();
		CriteriaQuery<T> query = em.getCriteriaBuilder().createQuery(classe);
		query.select(query.from(classe));

		List<T> lista = em.createQuery(query).getResultList();

		em.close();
		return lista;
	}

	public T buscaPorId(Integer id) {
		EntityManager em = new JPAUtil().getEntityManager();
		T instancia = em.find(classe, id);
		em.close();
		return instancia;
	}

	public int contaTodos() {
		EntityManager em = new JPAUtil().getEntityManager();
		long result = (Long) em.createQuery("select count(n) from usuario n")
				.getSingleResult();
		em.close();

		return (int) result;
	}

}
